package com.olc.railing.utils;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;


import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class CommUtils {
    private final static Pattern mobileRex = Pattern.compile("[1][3456789]\\d{9}");

/*    *//**
     * 校验电话号码
     *
     * @param mobile
     * @return
     *//*
    public static boolean isMobile(String mobile) {
        return mobile != null && mobile.trim().length() == 11;
    }*/

    /**
     * 检查手机上是否安装了指定的软件
     *
     * @param context
     * @param packageName：应用包名
     * @return
     */
    public static boolean isAvilible(Context context, String packageName) {
        //获取packagemanager
        final PackageManager packageManager = context.getPackageManager();
        //获取所有已安装程序的包信息
        List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
        //用于存储所有已安装程序的包名
        List<String> packageNames = new ArrayList<String>();
        //从pinfo中将包名字逐一取出，压入pName list中
        if (packageInfos != null) {
            for (int i = 0; i < packageInfos.size(); i++) {
                String packName = packageInfos.get(i).packageName;
                packageNames.add(packName);
            }
        }
        //判断packageNames中是否有目标程序的包名，有TRUE，没有FALSE
        return packageNames.contains(packageName);
    }

    public static String formatBankCard(String bankCard){
        if(TextUtils.isEmpty(bankCard)){
            return null;
        }

        int divisor = 4;
        int remain = bankCard.length()%divisor;
        if(remain==0){
            bankCard =   dealwithBank(bankCard, remain, divisor);
        }else if(remain==1){
            bankCard =  dealwithBank(bankCard, remain, divisor-1);
        }else if(remain==2){
            bankCard =   dealwithBank(bankCard, remain, divisor-2);
        }else if(remain==3){
            bankCard =  dealwithBank(bankCard, remain, divisor-3);
        }
       return bankCard;
    }

    private static String dealwithBank(String bankCard, int remain, int i2) {
        String num = bankCard.substring((bankCard.length() - (remain + i2)), bankCard.length() - remain) + " " + bankCard.substring(bankCard.length() - remain);
        String star = bankCard.substring(0, bankCard.length() - (remain + i2));
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < star.length(); i++) {
            if ((i + 1) % 4 == 0) {
                builder.append("* ");
            } else {
                builder.append("*");
            }
        }
        builder.append(num);
        return builder.toString();
    }



    /**
     * 字符串是否包含中文
     * @param str 待校验字符串
     * @return true 包含中文字符 false 不包含中文字符
     */
    public static boolean hasContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4E00-\u9FA5|\\！|\\，|\\。|\\（|\\）|\\《|\\》|\\“|\\”|\\？|\\：|\\；|\\【|\\】]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }
    /**
     * 校验电话号码
     *
     * @param mobile
     * @return
     */
    public static boolean isMobile(String mobile) {
        return mobile != null && mobile.trim().length() == 11 && mobileRex.matcher(mobile).matches();
    }

    public static byte[] BitmapToByteArray(Bitmap bitmap){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }
    public static Bitmap byteArrayToBitmap(byte[] images){
        Bitmap bitmap = BitmapFactory.decodeByteArray(images,0,images.length);
        return bitmap;
    }

    public static Bitmap filePathToBitmap(String path){
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        return bitmap;
    }


    /**

     * [获取应用程序版本名称信息]

     * @param context

     * @return 当前应用的版本名称

     */

    public static synchronized String getPackageName(Context context) {

        try {

            PackageManager packageManager = context.getPackageManager();

            PackageInfo packageInfo = packageManager.getPackageInfo(

                    context.getPackageName(), 0);
            Log.d("123","packageName=="+packageInfo.packageName);

            return packageInfo.packageName;

        } catch (Exception e) {

            e.printStackTrace();

        }

        return null;

    }

    public static boolean isCarNum(String carPlateNum){
        String regex = "^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z0-9]{1}[A-Z0-9]{1}([京津沪渝桂蒙宁新藏冀晋辽吉黑苏浙皖赣闽鲁粤鄂湘豫川云贵陕甘青琼])?[A-NP-Z0-9]{1}[A-NP-Z0-9]{3}([A-NP-Z0-9挂学警港澳领试超外]{1}|应急)([A-NP-Z0-9外])?)$|^([A-Z0-9]{7})$|^默A00000$|^(应急[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z0-9]{1}[A-NP-Z0-9]{4})$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(carPlateNum);
        return  m.matches();
    }
    public static String getDeviceSN() {
        String serial = null;

        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class);
            serial = (String)get.invoke(c, "ro.serialno");
        } catch (Exception var3) {
            var3.printStackTrace();
        }

        return serial;
    }

    /**
     * 获取一个不重复的UUID号
     *
     * @return
     */
    public static String getUUId() {
        int machineId = 1;//最大支持1-9个集群机器部署
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if (hashCodeV < 0) {//有可能是负数
            hashCodeV = -hashCodeV;
        }
        return machineId + String.format("%07d", hashCodeV);
    }
    public static void main(String[] args){
        System.out.println(formatBankCard("123412341234123412912"));
    }

    /**
     * 提供精确的加法运算。
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static String add(String v1, String v2) {
        BigDecimal b1;
        try {
            b1 = new BigDecimal(v1);
        } catch (NumberFormatException e) {
            b1 = new BigDecimal("0");
        }
        BigDecimal b2;
        try {
            b2 = new BigDecimal(v2);
        } catch (NumberFormatException e) {
            b2 = new BigDecimal("0");
        }
        return b1.add(b2).toString();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static String subtract(String v1, String v2) {
        BigDecimal b1;
        try {
            b1 = new BigDecimal(v1);
        } catch (NumberFormatException e) {
            b1 = new BigDecimal("0");
        }
        BigDecimal b2;
        try {
            b2 = new BigDecimal(v2);
        } catch (NumberFormatException e) {
            b2 = new BigDecimal("0");
        }
        return b1.subtract(b2).toString();
    }

    /**
     * 提供精确的乘法运算。
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static String multiply(String v1, String v2) {
        BigDecimal b1;
        try {
            b1 = new BigDecimal(v1);
        } catch (NumberFormatException e) {
            b1 = new BigDecimal("0");
        }
        BigDecimal b2;
        try {
            b2 = new BigDecimal(v2);
        } catch (NumberFormatException e) {
            b2 = new BigDecimal("0");
        }
        return b1.multiply(b2).toString();
    }

    /**
     * 提供精确的乘法运算。
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static String multiplySetScale0(String v1, String v2) {
        BigDecimal b1;
        try {
            b1 = new BigDecimal(v1);
        } catch (NumberFormatException e) {
            b1 = new BigDecimal("0");
        }
        BigDecimal b2;
        try {
            b2 = new BigDecimal(v2);
        } catch (NumberFormatException e) {
            b2 = new BigDecimal("0");
        }
        return b1.multiply(b2).setScale(0).toString();
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由 scale 参数指
     * 定精度，以后的数字四舍五入。
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static String divide(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1;
        try {
            b1 = new BigDecimal(v1);
        } catch (NumberFormatException e) {
            b1 = new BigDecimal("0");
        }
        BigDecimal b2;
        try {
            b2 = new BigDecimal(v2);
        } catch (NumberFormatException e) {
            b2 = new BigDecimal("0");
        }
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    public static String getPaySerialNo(){
        return "TY"+System.currentTimeMillis();
    }


    public static String silentInstallApkByReflect(String apkPath, Context context) {
//          LogUtils.d(TAG,"启动了静默升级！");
//        SharedConfig.getInstance(this).writeData(AppConfig.Key.UPGRADE_RESULT,true);
        String result = "";
        try {
            PackageManager packageManager = context.getPackageManager();
            Class<?> pmClz = packageManager.getClass();
            if (Build.VERSION.SDK_INT >= 21) {
                Class<?> aClass = Class.forName("android.app.PackageInstallObserver");
                Constructor<?> constructor = aClass.getDeclaredConstructor();
                constructor.setAccessible(true);
                Object installObserver = constructor.newInstance();
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, aClass, int.class, String.class);
                method.setAccessible(true);
                method.invoke(packageManager, Uri.fromFile(new File(apkPath)), installObserver, 2, null);
            } else {
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, Class.forName("android.content.pm.IPackageInstallObserver"), int.class, String.class);
                method.setAccessible(true);
                method.invoke(packageManager, Uri.fromFile(new File(apkPath)), null, 2, null);
            }
            result = "success";
        } catch (Exception e) {
            e.printStackTrace();
            result = e.toString();
        }
        return result;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public static void install(@NonNull Context context, @NonNull String path) throws Exception {
        File file=new File(path);
        String apkName=path.substring(path.lastIndexOf(File.separator)+1,path.lastIndexOf(".apk"));
        //获取PackageInstaller
        PackageInstaller packageInstaller = context.getPackageManager()
                .getPackageInstaller();
        PackageInstaller.SessionParams params=new PackageInstaller
                .SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
        PackageInstaller.Session session=null;
        OutputStream outputStream=null;
        FileInputStream inputStream=null;
        try {
            //创建Session
            int sessionId = packageInstaller.createSession(params);
            //开启Session
            session=packageInstaller.openSession(sessionId);
            //获取输出流，用于将apk写入session
            outputStream = session.openWrite(apkName, 0, -1);
            inputStream=new FileInputStream(file);
            byte[] buffer=new byte[4096];
            int n;
            //读取apk文件写入session
            while ((n=inputStream.read(buffer))>0){
                outputStream.write(buffer,0,n);
            }
            //写完需要关闭流，否则会抛异常“files still open”
            inputStream.close();
            inputStream=null;
            outputStream.flush();
            outputStream.close();
            outputStream=null;
            //配置安装完成后发起的intent，通常是打开activity
            Intent intent=new Intent();
            PendingIntent pendingIntent= PendingIntent.getActivity(context,0,intent,0);
            IntentSender intentSender = pendingIntent.getIntentSender();
            //提交启动安装
            session.commit(intentSender);

        } catch (IOException e) {
            throw new RuntimeException("Couldn't install package", e);
        } catch (RuntimeException e) {
            if (session != null) {
                session.abandon();
            }
            throw e;
        }finally {
            if(inputStream!=null){
                inputStream.close();
            }
            if(outputStream!=null){
                outputStream.close();
            }
        }

    }
    public static String getVerName(Context context) {
        String verName = "";
        try {
            verName = context.getPackageManager().
                    getPackageInfo(context.getPackageName(), 0).versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return verName;
    }

    public static long getVerCode(Context context) {
        int verCode = 0;
        try {
            verCode = context.getPackageManager().
                    getPackageInfo(context.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return verCode;
    }
    public static boolean isNetworkConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                return mNetworkInfo.isAvailable();
            }
        }
        return false;
    }
}
